using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Input;
using System.Windows;
using System.Collections;
using System.Windows.Media;
using Ricciolo.PaperBoy.Feeds;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;


namespace Ricciolo.PaperBoy.UI
{
    public class TreeView : System.Windows.Controls.TreeView
    {

        public TreeView()
        {
            this.Items.CurrentChanged += new EventHandler(Items_CurrentChanged);

            ScrollViewer.SetIsDeferredScrollingEnabled(this, true);
            VirtualizingStackPanel.SetVirtualizationMode(this, VirtualizationMode.Recycling);
            VirtualizingStackPanel.SetIsVirtualizing(this, true);
        }

        void Items_CurrentChanged(object sender, EventArgs e)
        {
            // Auto select current item
            SetSelectedToCurrent();
        }

        private void SetSelectedToCurrent()
        {
            TreeViewItem titem = this.ItemContainerGenerator.ContainerFromItem(this.Items.CurrentItem) as TreeViewItem;
            if (titem != null && !titem.IsSelected)
            {
                titem.IsSelected = true;
            }
        }

        protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            //base.OnItemsChanged(e);

            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
            {
                SetSelectedToCurrent();
            }
        }

        protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
        {
            base.OnItemsSourceChanged(oldValue, newValue);

            // Refresh child items
            IRefresh refresh;
            if (this.ItemsSource is ICollectionView)
                refresh = ((ICollectionView)this.ItemsSource).SourceCollection as IRefresh;
            else
                refresh = this.ItemsSource as IRefresh;
            if (refresh != null)
                refresh.Refresh();
        }

        protected override System.Windows.DependencyObject GetContainerForItemOverride()
        {
            return new TreeViewItem();
        }


    }

    public class TreeViewItem : System.Windows.Controls.TreeViewItem
    {

        public TreeViewItem()
        {
            this.Items.CurrentChanged += new EventHandler(Items_CurrentChanged);
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new TreeViewItem();
        }

        void Items_CurrentChanged(object sender, EventArgs e)
        {
            // Auto select current item
            SetSelectedToCurrent();
        }

        private void SetSelectedToCurrent()
        {
            TreeViewItem titem = this.ItemContainerGenerator.ContainerFromItem(this.Items.CurrentItem) as TreeViewItem;
            if (titem != null && !titem.IsSelected)
            {
                titem.IsSelected = true;
            }
        }

        protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);

            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
            {
                SetSelectedToCurrent();
            }
        }

        protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
        {
            base.OnItemsSourceChanged(oldValue, newValue);

            if (this.IsExpanded)
                RefreshItems();
        }

        protected override void OnExpanded(RoutedEventArgs e)
        {
            base.OnExpanded(e);

            RefreshItems();
        }

        private void RefreshItems()
        {
            // Refresh child items
            IRefresh refresh;
            if (this.ItemsSource is ICollectionView)
                refresh = ((ICollectionView)this.ItemsSource).SourceCollection as IRefresh;
            else
                refresh = this.ItemsSource as IRefresh;
            if (refresh != null)
                refresh.Refresh();
        }

        protected override void OnCollapsed(RoutedEventArgs e)
        {
            base.OnCollapsed(e);

            // Remove child items
            IList list;
            if (this.ItemsSource is ICollectionView)
                list = ((ICollectionView)this.ItemsSource).SourceCollection as IList;
            else
                list = this.ItemsSource as IList;
            if (list != null)
                list.Clear();

            // Remove visual elements
            ((IItemContainerGenerator)this.ItemContainerGenerator).RemoveAll();
        }

        protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;
                this.Focus();
            }
            base.OnMouseRightButtonDown(e);
        }

    }

    public class PrepareContainerEventArgs : EventArgs
    {
        private readonly DependencyObject _element;
        private readonly object _item;


        public PrepareContainerEventArgs(DependencyObject element, object item)
        {
            _element = element;
            _item = item;
        }

        public DependencyObject Element
        {
            get { return _element; }
        }

        public object Item
        {
            get { return _item; }
        }
    }
}
